package com.lt.flashcard.model.entity;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

/**
 * @author tam.nguyentrung
 * @version 1.0
 * @created 15-Aug-2012 17:37:08
 */
@Entity
@Table(name = "flashcard")
public class Flashcard implements java.io.Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;

    /**
     * hinh vi du cho flashcard
     */
    private String image = "";
    /**
     * include phonetics, examples, etc
     */
    private String notes = "";
    private String soundfront = "";
    private String soundback = "";
    /**
     * t? English
     */
    private String term = "";
    /**
     * Dinh nghia cua tu
     */
    private String definition = "";
    /**
     * have learned?
     */
    private int status = 0;
    /**
     * The order of flashcard in a set
     */
    private int weight = 999;
    private FlashcardSet flashcardSet;
    private Date created = new Date();
    /**
     * Point to the original flashcard set of this flashcard
     */
    private FlashcardSet oriflashcardset;
    /**
     * Learning status, this is the overall process of this flashcard
     */
    private int learnStatus = LEARNSTATUS_LEARNING;
    /**
     * Start learning but not finish
     */
    public static final int LEARNSTATUS_LEARNING = 0;
    /**
     * Finish learning
     */
    public static final int LEARNSTATUS_FINISH = 1;
    /**
     * Current learning level
     */
    private int learnLevel = LEARNLEVEL_NEW;
    /**
     * The start level of learning
     */
    public static final int LEARNLEVEL_NEW = -1;
    public static final int LEARNLEVEL_0 = 0;
    public static final int LEARNLEVEL_1 = 1;
    public static final int LEARNLEVEL_7 = 7;
    public static final int LEARNLEVEL_7_1 = 71;
    public static final int LEARNLEVEL_FINISH = 8;
    /**
     * The date for next learn the next level
     */
    private Date learnNextdate;
    private Date lasttestdate;
    private int testresult0 = 0;
    private int testresult1 = 0;
    private int testresult7 = 0;
    private int lasttesttype = -1;
    /**
     * learn this level or not
     */
    private byte hasLearnt = LEARN_NOTYET;

    public static final byte LEARN_HASLEARNT = 1;
    public static final byte LEARN_NOTYET = 0;
    /**
     * The result of the test of lastest test
     */
    private int testStatus = TESTSTATUS_NOTYET;
    public static final int TESTSTATUS_NOTYET = -1;
    public static final int TESTSTATUS_FAIL = 0;
    public static final int TESTSTATUS_RIGHT = 1;

    private int admin = ADMIN_NO;
    public static final int ADMIN_YES = 1;
    public static final int ADMIN_NO = 0;
    public static final int ADMIN_BUY = 2;
    private String phonetic = "";
    private String wordtype = "";
    private String vietnamese = "";
    private String symnonym = "";
    private String nounthing = "";
    private String nounperson = "";
    private String verb = "";
    private String adjective = "";
    private String adverb = "";
    private String category = "";
    private String english = "";

    public Flashcard(String image, String notes, String soundFront, String soundBack, String term, String definition, int status,
            int weight, Date created) {
        this.image = image;
        this.notes = notes;
        this.soundfront = soundFront;
        this.soundback = soundBack;
        this.term = term;
        this.definition = definition;
        this.status = status;
        this.weight = weight;
        this.created = created;
    }

    /**
     * Duplicate a flashcard to new one
     * 
     * @param flashcard
     */
    public Flashcard(Flashcard flashcard) {
        this.definition = flashcard.definition;
        this.image = flashcard.image;
        this.notes = flashcard.notes;
        this.soundfront = flashcard.soundfront;
        this.soundback = flashcard.soundback;
        this.term = flashcard.term;
        this.status = flashcard.status;
        this.weight = flashcard.weight;
        this.created = flashcard.created;
    }

    public Flashcard() {
    }

    /**
     * Clone a flashcard
     */
    @Override
    @Transient
    public Flashcard clone() {
        Flashcard fc = new Flashcard();
        fc.setImage(getImage());
        fc.setNotes(getNotes());
        fc.setSoundFront(getSoundFront());
        fc.setSoundBack(getSoundBack());
        fc.setTerm(getTerm());
        fc.setDefinition(getDefinition());
        fc.setStatus(getStatus());
        fc.setWeight(getWeight());
        fc.setFlashcardSet(null);
        fc.setOriflashcardset(getFlashcardSet());
        fc.setAdmin(ADMIN_NO);
        fc.setPhonetic(getPhonetic());
        fc.setWordtype(getWordtype());
        fc.setVietnamese(getVietnamese());
        fc.setSymnonym(getSymnonym());
        fc.setNounthing(getNounthing());
        fc.setNounperson(getNounperson());
        fc.setVerb(getVerb());
        fc.setAdjective(getAdjective());
        fc.setAdverb(getAdverb());
        fc.setEnglish(getEnglish());
        fc.setCategory(getCategory());

        return fc;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", unique = true, nullable = false)
    public Long getId() {
        return this.id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Column(name = "image")
    public String getImage() {
        return image;
    }

    public void setImage(String image) {
        this.image = image;
    }

    @Column(name = "notes", nullable = false)
    public String getNotes() {
        return notes;
    }

    public void setNotes(String notes) {
        this.notes = notes;
    }

    @Column(name = "soundfront")
    public String getSoundFront() {
        return soundfront;
    }

    public void setSoundFront(String soundFront) {
        this.soundfront = soundFront;
    }

    @Column(name = "soundback")
    public String getSoundBack() {
        return soundback;
    }

    public void setSoundBack(String soundBack) {
        this.soundback = soundBack;
    }

    @Column(name = "term", nullable = false)
    public String getTerm() {
        return term;
    }

    public void setTerm(String term) {
        this.term = term;
    }

    @Column(name = "definition", nullable = false)
    public String getDefinition() {
        return definition;
    }

    public void setDefinition(String definition) {
        this.definition = definition;
    }

    @Deprecated
    @Column(name = "status", nullable = false)
    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "flashcardset_id", nullable = false)
    public FlashcardSet getFlashcardSet() {
        return flashcardSet;
    }

    public void setFlashcardSet(FlashcardSet flashcardSet) {
        this.flashcardSet = flashcardSet;
    }

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "created", nullable = false, length = 0)
    public Date getCreated() {
        return created;
    }

    public void setCreated(Date created) {
        this.created = created;
    }

    @Column(name = "weight", nullable = false)
    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }

    @Column(name = "learn_level", nullable = false)
    public int getLearnLevel() {
        return this.learnLevel;
    }

    public void setLearnLevel(int learnLevel) {
        this.learnLevel = learnLevel;
    }

    /**
     * The date for next testing
     * 
     * @return
     */
    @Temporal(TemporalType.DATE)
    @Column(name = "learn_nextdate", length = 0)
    public Date getLearnNextdate() {
        return this.learnNextdate;
    }

    public void setLearnNextdate(Date learnNextdate) {
        this.learnNextdate = learnNextdate;
    }

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "lasttestdate", length = 10)
    public Date getLasttestdate() {
        return this.lasttestdate;
    }

    public void setLasttestdate(Date lasttestdate) {
        this.lasttestdate = lasttestdate;
    }

    @Column(name = "testresult0", nullable = false)
    public int getTestresult0() {
        return this.testresult0;
    }

    public void setTestresult0(int testresult0) {
        this.testresult0 = testresult0;
    }

    @Column(name = "testresult1", nullable = false)
    public int getTestresult1() {
        return this.testresult1;
    }

    public void setTestresult1(int testresult1) {
        this.testresult1 = testresult1;
    }

    @Column(name = "testresult7", nullable = false)
    public int getTestresult7() {
        return this.testresult7;
    }

    public void setTestresult7(int testresult7) {
        this.testresult7 = testresult7;
    }

    @Column(name = "lasttesttype", nullable = false)
    public int getLasttesttype() {
        return this.lasttesttype;
    }

    public void setLasttesttype(int lasttesttype) {
        this.lasttesttype = lasttesttype;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "oriflashcardset_id")
    public FlashcardSet getOriflashcardset() {
        return this.oriflashcardset;
    }

    public void setOriflashcardset(FlashcardSet oriflashcardset) {
        this.oriflashcardset = oriflashcardset;
    }

    /**
     * Not meaning
     * 
     * @return
     */
    @Deprecated
    @Column(name = "learn_status", nullable = false)
    public int getLearnStatus() {
        return this.learnStatus;
    }

    public void setLearnStatus(int learnStatus) {
        this.learnStatus = learnStatus;
    }

    /**
     * If learnlevel > -1, ---> learnt, not yet otherwise
     * 
     * @return
     */
    @Deprecated
    @Column(name = "hasLearnt", nullable = false)
    public byte getHasLearnt() {
        return this.hasLearnt;
    }

    @Deprecated
    public void setHasLearnt(byte hasLearnt) {
        this.hasLearnt = hasLearnt;
    }

    @Column(name = "test_status", nullable = false)
    public int getTestStatus() {
        return this.testStatus;
    }

    public void setTestStatus(int testStatus) {
        this.testStatus = testStatus;
    }

    @Column(name = "admin", nullable = false)
    public int getAdmin() {
        return this.admin;
    }

    public void setAdmin(int admin) {
        this.admin = admin;
    }

    @Column(name = "phonetic", nullable = false, length = 50)
    public String getPhonetic() {
        return this.phonetic;
    }

    public void setPhonetic(String phonetic) {
        this.phonetic = phonetic;
    }

    @Column(name = "wordtype", nullable = false, length = 15)
    public String getWordtype() {
        return this.wordtype;
    }

    public void setWordtype(String wordtype) {
        this.wordtype = wordtype;
    }

    @Column(name = "vietnamese", nullable = false)
    public String getVietnamese() {
        return this.vietnamese;
    }

    public void setVietnamese(String vietnamese) {
        this.vietnamese = vietnamese;
    }

    @Column(name = "symnonym", nullable = false, length = 50)
    public String getSymnonym() {
        return this.symnonym;
    }

    public void setSymnonym(String symnonym) {
        this.symnonym = symnonym;
    }

    @Column(name = "nounthing", nullable = false, length = 50)
    public String getNounthing() {
        return this.nounthing;
    }

    public void setNounthing(String nounthing) {
        this.nounthing = nounthing;
    }

    @Column(name = "nounperson", nullable = false, length = 50)
    public String getNounperson() {
        return this.nounperson;
    }

    public void setNounperson(String nounperson) {
        this.nounperson = nounperson;
    }

    @Column(name = "verb", nullable = false, length = 50)
    public String getVerb() {
        return this.verb;
    }

    public void setVerb(String verb) {
        this.verb = verb;
    }

    @Column(name = "adjective", nullable = false, length = 50)
    public String getAdjective() {
        return this.adjective;
    }

    public void setAdjective(String adjective) {
        this.adjective = adjective;
    }

    @Column(name = "adverb", nullable = false, length = 50)
    public String getAdverb() {
        return this.adverb;
    }

    public void setAdverb(String adverb) {
        this.adverb = adverb;
    }

    @Column(name = "category", nullable = false, length = 50)
    public String getCategory() {
        return this.category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    @Column(name = "english", nullable = false)
    public String getEnglish() {
        return this.english;
    }

    public void setEnglish(String english) {
        this.english = english;
    }

    @Transient
    public boolean isAlreadyLearnt() {
        return learnLevel > -1;
    }
}